<?php
/**
 * Description:
 *
 * @author      Eden
 * @datetime    2017/2/9 13:04
 * @copyright   WuHan HuQi Technology Co.,Ltd.
 * @url         http://cnhuqi.com
 */

class ExpressPrice_Model extends CI_Model
{

    private $eError = '';

    /**
     * 初始化
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 计算物流费用
     * @param int $userid
     * @return array|int
     */
    public function price($userid = 0)
    {
        $db = clone($this->db);
        $where = ['c.userId' => $userid, 'c.selected' => 1];
        $q = $db->select('g.id as goodsId, g.baseId, g.expType, g.expAmount, c.num,
            c.selected, r.id as ruleId, r.oldPrice, r.salePrice, r.purchaserPrice, r.expressWeight')
            ->from('user_car as c')
            ->join('base_goods as g', 'g.id = c.goodsId')
            ->join('base_goods_rule as r', 'r.id=c.ruleId')
            ->where($where)
            ->get();
        $rows = $q->result_array();
        if (empty($rows)) {
            return 0;
        }

        $baseIds = [];
        foreach ($rows as $row) {
            $baseIds[] = intval($row['baseId']);
        }

        if (empty($baseIds)) {
            return 0;
        }

        $config = $this->getExpConfig($baseIds);
        $result = [
            'total' => 0,
            'base' => []
        ];
        foreach ($rows as $row) {
            if ($row['expType'] == 2) {
                // 一口价
                $result['total'] += $row['expAmount'];
                $i = intval($row['expAmount']);
            } else {
                // 模板计价
                $conf = isset($config[$row['baseId']]) ? $config[$row['baseId']] : [];
                if (empty($conf)) {
                    continue;
                }
                if ($conf['payer'] == 'buyer') {
                    // 用户给钱
                    if ($row['expressWeight'] == 0) {
                        $i = 0;
                    } else {
                        $totalWeight = $row['expressWeight'] * $row['num'];

                        $left = $totalWeight - $conf['firstWeight'];
                        if ($left <= 0) {
                            $result['total'] += $conf['firstCost'];
                            $i = intval($conf['firstCost']);
                        } else {
                            $i = ceil($left / $conf['incrWeight']) * $conf['incrCost'];
                            $result['total'] += $i;
                        }
                    }
                } else {
                    $i = 0;
                }
            }

            $key = (string) $row['baseId'];
            if (!isset($result['base'][$key])) {
                $result['base'][$key] = $i;
            } else {
                $result['base'][$key] += $i;
            }
        }

        return $result;
    }

    /**
     * 配置
     * @param $baseIds
     * @return array
     */
    private function getExpConfig($baseIds)
    {
        $db = clone($this->db);
        $q = $db->select('t.baseId, t.payer, w.firstWeight, w.firstCost, w.incrWeight, incrCost')
            ->from('express_template as t')
            ->join('express_weight as w', 't.id=w.tmpId')
            ->where_in('t.baseId', $baseIds)
            ->get();
        $rows = $q->result_array();
        $res = [];
        foreach ($rows as $row) {
            $res[$row['baseId']] = $row;
        }
        return $res;
    }

    /**
     * $goods = array(
     *      ['goodsId' => 1, 'price' => '', 'expressWeight' => 1.0 'num' => 2],
     *      ...
     * );
     * @param array $goods
     */
    public function calc(Array $goods, $voucher = '')
    {
        if (empty($goods)) {
            $this->eError = '没有选择商品';
            return false;
        }

        $config = $this->_getShippingCosts();
        $totalWeight = 0;
        $totalAmount = 0;
        foreach ($goods as $item) {
            if ($item['expType'] == 1) {
                // 按重量
                if ($config['payer'] == 'buyer') {
                    // 用户给钱
                    $totalWeight += $item['expressWeight'] * $item['num'];
                } else {
                    // 卖家给钱
                    $totalWeight += 0;
                }
            } else {
                // 一口价
                $totalAmount += $item['expAmount'] * $item['num'];
            }
        }

        // 重量不计
        if ($totalWeight == 0) {
            return $totalAmount;
        }

        // 重量小于首重
        $costs = $config['costs'];
        if ($totalWeight <= $costs['firstWeight']) {
            return $totalAmount + $costs['firstCost'] * 100;
        }

        $left = $totalWeight - $costs['firstWeight'];
        $amount = ceil($left / $costs['incrWeight']) * $costs['incrCost'] + $costs['firstCost'];
        return $amount * 100 + $totalAmount;
    }

    /**
     * 计算运费
     * @param int $totalWeight
     * @return float|int
     */
    private function getExpressCosts($totalWeight = 0)
    {
        if ($totalWeight == 0) {
            return 0;
        }

        $config = $this->_getShippingCosts();
        if ($config['payer'] == 'buyer') {
            $costs = $config['costs'];
            $firstWeight = $costs['firstWeight'];
            $firstCost = $costs['firstCost'];
            $incrWeight = $costs['incrWeight'];
            $incrCost = $costs['incrCost'];
            if ($firstWeight >= $totalWeight) {
                return $firstCost;
            } else {
                $left = $totalWeight - $firstWeight;
                return ceil($left / $incrWeight) * $incrCost + $firstCost;
            }

        } else {
            return 0;
        }
    }

    /**
     * 获取跟客户端一样的物流配置
     * @return array
     */
    private function _getShippingCosts()
    {
        $default = array(
            'payer' => 'seller',
            'costs' => []
        );
        // 前期只考虑到统一的价格的情况,没有进行区域区分
        $db = clone($this->db);
        $q = $db->get_where('express_template', array('using' => 1));
        $row = $q->row_array();
        if (!$row) {
            return $default;
        }

        if ($row['payer'] == 'seller') {
            return $default;
        }

        $payer = $row['payer'];
        if ($row['payType'] == 'weight') {
            $q = $this->db->get_where('express_weight', array('tmpId' => $row['id']));
            $row = $q->row_array();
            if (empty($row)) {
                return $default;
            }
            $default['payer'] = $payer;
            $default['costs'] = array(
                'firstWeight' => doubleval($row['firstWeight']),
                'firstCost' => doubleval($row['firstCost']),
                'incrWeight' => doubleval($row['incrWeight']),
                'incrCost' => doubleval($row['incrCost'])
            );
        }

        return $default;
    }

    /**
     * @return string
     */
    public function getErrorString()
    {
        return $this->eError;
    }
}
